<template>
  <div class="validate-input-container pb-3">
    <input v-if="tag !== 'textarea'" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"
      :class="{ 'is-invalid': inputRef.error }" v-model="inputRef.val" @blur="ValidateInput" v-bind="attrs" />
    <textarea v-else class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"
      :class="{ 'is-invalid': inputRef.error }" v-model="inputRef.val" @blur="ValidateInput" v-bind="attrs"></textarea>
    <span class="invalid-feedback" v-if="inputRef.error">{{ inputRef.message }}</span>
  </div>
</template>

<script setup lang="ts">
import { computed } from '@vue/reactivity';
import { reactive, useAttrs, onMounted } from 'vue';
import { emitter } from '../util/util_mitt';
export interface RuleProp {
  type: 'required' | 'email' | 'range' | 'custom'
  message?: string
  max?: {
    message: string
    length: number
  }
  min?: {
    message: string
    length: number
  }
  validator?: () => boolean
}
export type RulesProp = RuleProp[]
type TagType = 'input' | 'textarea'
interface Props {
  rules: RulesProp,
  modelValue?: string
  tag: TagType
}
// 解构 Props 值里的rules, modelValue
let props = defineProps<Props>()
// 获取自定义时间名称
let emits = defineEmits(['update:modelValue'])

// 表单验证初始值
const inputRef = reactive({
  val: computed({
    get: () => props.modelValue || '',
    set: val => {
      emits('update:modelValue', val)
    }
  }),
  error: false,
  message: ''
})
// 邮箱验证规则
const emailReg = /^\w+@[a-zA-Z0-9]{2,10}(?:\.[a-z]{2,4}){1,3}$/
// blur事件（验证表单是否正常）
const ValidateInput = () => {
  if (props.rules) {
    const allPassed = props.rules.every(rule => {
      let passed = true
      inputRef.message = rule.message ?? (rule.max?.message as string) + '并且' + (rule.min?.message as string)
      switch (rule.type) {
        // 验证为不为空
        case 'required':
          passed = (inputRef.val.trim() !== '')
          break;
        // 验证邮箱是否正确
        case 'email':
          passed = emailReg.test(inputRef.val.trim())
          break;
        case 'range':
          passed = inputRef.val.length >= (props.rules[1].min?.length as number) && inputRef.val.length <= (props.rules[1].max?.length as number)
          break;
        case 'custom':
          passed = rule.validator ? rule.validator() : true
          break;
        default:
          break;
      }
      return passed
    })
    // 显示不显示 错误提示
    inputRef.error = !allPassed
    // 返回 有没有 错误的every
    return allPassed
  }
  // 如果执行到这说明没有错误
  return true
}
// 获取外部的的非props 属性
let attrs = useAttrs()
onMounted(() => {
  emitter.emit('form-item-created', ValidateInput)
  emitter.emit('clear-inputs', clearInputs)
})
const clearInputs = () => {
  emits('update:modelValue', '')
  inputRef.val = ''
}
</script>
